package com.stockz.indicator;

import com.stockz.ui.swing.charting.util.MathUtil;

public class IndicatorUtil {

	public static double simpleMovingAverage(double[] values){
		return MathUtil.avg(values);
	}
	
	public static double[] simpleMovingAverage(double[] barValues, int span){
		if(barValues != null && span > 0 && barValues.length > span){
			double sum = 0;
			double[] values = new double[barValues.length];
			for(int i = barValues.length-1; i >=0; i--){
				if(barValues[i] == 0){
					continue;
				}
				if(i > barValues.length - span){
					values[i] = 0;
				}else if(i ==  barValues.length - span){
					values[i] = sum/span;
				}else{
					values[i] = sum/span;
					sum -= barValues[i+span];
				}
				sum += barValues[i];
			}
			return values;
		}
		return new double[0];
	}
	
	
	public static double stochastics(double[] values){
		if(values != null && values.length > 0){
			double min = Double.MAX_VALUE;
			double max = Double.MIN_VALUE;
			for(int i = 0; i < values.length; i++){
				if(values[i] > max) max = values[i];
				if(values[i] < min) min = values[i];
			}
			if(max == min){
				return 0;
			}else{
				return (((values[0])-min)*100)/(max-min);
			}
		}
		return 0;
	}
	
	public static double[] stochastics(double[] barValues, int span){
		if(barValues != null && span > 0 && barValues.length > span){
			double[] values = new double[barValues.length];
			double min = Double.MAX_VALUE;
			double max = Double.MIN_VALUE;
			for(int i = barValues.length-1; i >=0; i--){
				if(barValues[i] == 0){
					continue;
				}
				if(i > barValues.length - span){
					values[i] = 0;
					if(barValues[i] > max) max = barValues[i];
					if(barValues[i] < min) min = barValues[i];
				}else if(i ==  barValues.length - span){
					if(barValues[i] > max) max = barValues[i];
					if(barValues[i] < min) min = barValues[i];
					values[i] =  (((barValues[0])-min)*100)/(max-min);
				}else{
					if(max == barValues[i+span]) max = MathUtil.max(barValues, i, i+span);
					if(min == barValues[i+span]) min = MathUtil.min(barValues, i, i+span);
					values[i] =  (((barValues[0])-min)*100)/(max-min);
				}
			}
			return values;
		}
		return new double[0];
	}
	
	
	public static double[][] bollingerBands(double[] barValues, int span, double mult,
			boolean modified, boolean exponencial){
		if(barValues != null){
			double[][] values = new double[3][barValues.length];
			double sum = 0; 
			double sumSquared = 0;
			if(barValues.length > 0 && span > 1 && span <= barValues.length){
				for(int i = barValues.length-1; i >=0; i--){
					if(barValues[i] == 0){
						continue;
					}
					if(i > barValues.length - span){
						
					}else if(i ==  barValues.length - span){
						values[1][i] = sum/span;
						double stdDev = Math.sqrt((span * sumSquared - (sum * sum))/ (span * (span- 1)));
						values[0][i] = values[1][i] + mult*stdDev;
						values[2][i] = values[1][i] - mult*stdDev;
					}else{
						values[1][i] = sum/span;
						double stdDev = Math.sqrt((span * sumSquared - (sum * sum))/ (span * (span- 1)));
						values[0][i] = values[1][i] + mult*stdDev;
						values[2][i] = values[1][i] - mult*stdDev;
						
						sum -= barValues[i+span];
						sumSquared -= (barValues[i+span]*barValues[i+span]);
					}
					sum += barValues[i];
					sumSquared += (barValues[i]*barValues[i]);
				}
			}
			return values;
		}
		return new double[0][0];
	}
	
}
